



#include "Superficie_Triangular.h"


Superificie_Triangular::Superificie_Triangular()
{


}

Superificie_Triangular::Superificie_Triangular(char *filenamePuntos, char *filenameIndices)
{
	charFnamePtosSupTriang = filenamePuntos;
	charFnameIndsSupTriang = filenameIndices;
}

void Superificie_Triangular::CargarSuperficieTriangular_2_0()
{
	int x, y, z;
	float fx, fy, fz;
	FILE *fileInPuntos;
	FILE *fileInIndices;
	char lineaActual[255]; 

	fileInIndices = fopen(charFnameIndsSupTriang, "rt");
	fileInPuntos = fopen(charFnamePtosSupTriang, "rt");

	//Almacena los indices

	readstr(fileInIndices,lineaActual);
	sscanf(lineaActual, "Indices: %d\n", &intNroTriangs);

	for (unsigned int loop = 0; loop < intNroTriangs; loop++)
	{	
		readstr(fileInIndices,lineaActual);
		sscanf(lineaActual, "%i, %i, %i,", &x, &y, &z);
				
		Indice objIndiceTemp(x, y, z);

		objIndices.push_back(objIndiceTemp);
	}
	fclose(fileInIndices);

	//Almacena los puntos

	readstr(fileInPuntos,lineaActual);
	sscanf(lineaActual, "Vertices: %d\n", &intNroVertices);
	
	for (unsigned int loop = 0; loop < intNroVertices; loop++)
	{
		readstr(fileInPuntos,lineaActual);
		sscanf(lineaActual, "%f %f %f", &fx, &fy, &fz);

		Vertice* objVerticeTemp;
		
		if(enmSesionSup == TRANSPORTAR_CUBOS)
		{
			objVerticeTemp = new Vertice((float)(fx), (float)(fy), (float)fz); 
		}
		else if(enmSesionSup == ORDENAR_CUBOS)
		{
			objVerticeTemp = new Vertice((float)(fx), (float)(fy), (float)fz); 
		}
		else if(enmSesionSup == SIMULACION_HIGADO)
		{
			objVerticeTemp = new Vertice((float)(fx-833.0), (float)(fy-240.0), (float)fz); 
		}
		else
		{
			throw new exception;
		}

		objVerticeTemp->setID(loop);

		objVertices.push_back(objVerticeTemp);
	}
	fclose(fileInPuntos);

	int intIndiceTemporal1;
	int intIndiceTemporal2;
	int intIndiceTemporal3;

	int intTemporal = 0;

	Borde borde1;
	Borde borde2;
	Borde borde3;

	unsigned int intNroBordes1 = 0;
	unsigned int intNroBordes2 = 0;
	unsigned int intNroBordes3 = 0;
	unsigned int intInsertBorde = 0;

	intNroBordes = 0;

	//Almacena los triangulos

	for(unsigned int loop = 0; loop < intNroTriangs; loop++)
	{
		Indice objIndiceTemp;

		Triangulo objTrianguloTemp(objVertices[objIndices[loop].getIndice1()],
			objVertices[objIndices[loop].getIndice2()], 
			objVertices[objIndices[loop].getIndice3()]);

		//Asignando ID al triangulo
		objTrianguloTemp.setID(loop);
		objTrianguloTemp.IncializarVecinos();

		intIndiceTemporal1 = objIndices[loop].getIndice1();
		intIndiceTemporal2 = objIndices[loop].getIndice2();
		intIndiceTemporal3 = objIndices[loop].getIndice3();

		objIndiceTemp = objIndices[loop];
		objTrianguloTemp.setIndice(objIndiceTemp);

		//Calcula Normales de cada triangulo
		objTrianguloTemp.CalcularNormal();

		objTriangulos.push_back(objTrianguloTemp);

		//Determina las relaciones entre los vertices y las caras
		objVertices[intIndiceTemporal1]->setOneConCara(loop);
		objVertices[intIndiceTemporal1]->Add1ConCara();
		objVertices[intIndiceTemporal1]->setOneNormalCara(objTrianguloTemp.getNormal2());
		objVertices[intIndiceTemporal2]->setOneConCara(loop);
		objVertices[intIndiceTemporal2]->Add1ConCara();
		objVertices[intIndiceTemporal2]->setOneNormalCara(objTrianguloTemp.getNormal2());
		objVertices[intIndiceTemporal3]->setOneConCara(loop);
		objVertices[intIndiceTemporal3]->Add1ConCara();
		objVertices[intIndiceTemporal3]->setOneNormalCara(objTrianguloTemp.getNormal2());


		intTemporal = 0;
		intNroBordes1 = 0;
		intNroBordes2 = 0;
		intNroBordes3 = 0;

		//Crea los bordes y determina los vertices relacionados
		if(loop == 0)
		{
			borde1.setVertice1(objVertices[intIndiceTemporal1]);
			borde1.setIndice1(intIndiceTemporal1);
			borde1.setVertice2(objVertices[intIndiceTemporal2]);
			borde1.setIndice2(intIndiceTemporal2);

			objVertices[intIndiceTemporal1]->setOneConVertice(intIndiceTemporal2);
			objVertices[intIndiceTemporal1]->Add1ConVertice();
			objVertices[intIndiceTemporal1]->setOneConBorde(0);
			objVertices[intIndiceTemporal1]->Add1ConBorde();
				
			objVertices[intIndiceTemporal2]->setOneConVertice(intIndiceTemporal1);
			objVertices[intIndiceTemporal2]->Add1ConVertice();
			objVertices[intIndiceTemporal2]->setOneConBorde(0);
			objVertices[intIndiceTemporal2]->Add1ConBorde();

			objBordes.push_back(borde1);
			intInsertBorde++;

			borde2.setVertice1(objVertices[intIndiceTemporal2]);
			borde2.setIndice1(intIndiceTemporal2);
			borde2.setVertice2(objVertices[intIndiceTemporal3]);
			borde2.setIndice2(intIndiceTemporal3);

			objVertices[intIndiceTemporal2]->setOneConVertice(intIndiceTemporal3);
			objVertices[intIndiceTemporal2]->Add1ConVertice();
			objVertices[intIndiceTemporal2]->setOneConBorde(1);
			objVertices[intIndiceTemporal2]->Add1ConBorde();
				
			objVertices[intIndiceTemporal3]->setOneConVertice(intIndiceTemporal2);
			objVertices[intIndiceTemporal3]->Add1ConVertice();
			objVertices[intIndiceTemporal3]->setOneConBorde(1);
			objVertices[intIndiceTemporal3]->Add1ConBorde();

			objBordes.push_back(borde2);
			intInsertBorde++;

			borde3.setVertice1(objVertices[intIndiceTemporal3]);
			borde3.setIndice1(intIndiceTemporal3);
			borde3.setVertice2(objVertices[intIndiceTemporal1]);
			borde3.setIndice2(intIndiceTemporal1);

			objVertices[intIndiceTemporal3]->setOneConVertice(intIndiceTemporal1);
			objVertices[intIndiceTemporal3]->Add1ConVertice();
			objVertices[intIndiceTemporal3]->setOneConBorde(2);
			objVertices[intIndiceTemporal3]->Add1ConBorde();
				
			objVertices[intIndiceTemporal1]->setOneConVertice(intIndiceTemporal3);
			objVertices[intIndiceTemporal1]->Add1ConVertice();
			objVertices[intIndiceTemporal1]->setOneConBorde(2);
			objVertices[intIndiceTemporal1]->Add1ConBorde();

			objBordes.push_back(borde3);
			intInsertBorde++;

			intNroBordes += 2;
		}
		else
		{
			for(unsigned int i=0;i<=intNroBordes;i++)
			{
				//cout << "Indice1: " << objBordes[i].getIndice1() << endl;
				//cout << "Indice2: " << objBordes[i].getIndice2() << endl;

				if(objBordes[i].getIndice1()!=intIndiceTemporal1 || objBordes[i].getIndice2()!=intIndiceTemporal2)
				{
					if(objBordes[i].getIndice1()!=intIndiceTemporal2 || objBordes[i].getIndice2()!=intIndiceTemporal1)
					{
						intNroBordes1++;
					}
				}


				if(objBordes[i].getIndice1()!=intIndiceTemporal2 || objBordes[i].getIndice2()!=intIndiceTemporal3)
				{
					if(objBordes[i].getIndice1()!=intIndiceTemporal3 || objBordes[i].getIndice2()!=intIndiceTemporal2)
					{
						intNroBordes2++;
					}
				}


				if(objBordes[i].getIndice1()!=intIndiceTemporal3 || objBordes[i].getIndice2()!=intIndiceTemporal1)
				{
					if(objBordes[i].getIndice1()!=intIndiceTemporal1 || objBordes[i].getIndice2()!=intIndiceTemporal3)
					{
						intNroBordes3++;
					}	
				}
			}

			if(intNroBordes1-1 == intNroBordes)
			{
				borde1.setVertice1(objVertices[intIndiceTemporal1]);
				borde1.setIndice1(intIndiceTemporal1);
				borde1.setVertice2(objVertices[intIndiceTemporal2]);
				borde1.setIndice2(intIndiceTemporal2);

				objVertices[intIndiceTemporal1]->setOneConVertice(intIndiceTemporal2);
				objVertices[intIndiceTemporal1]->Add1ConVertice();
				objVertices[intIndiceTemporal1]->setOneConBorde(intInsertBorde);
				objVertices[intIndiceTemporal1]->Add1ConBorde();
				
				objVertices[intIndiceTemporal2]->setOneConVertice(intIndiceTemporal1);
				objVertices[intIndiceTemporal2]->Add1ConVertice();
				objVertices[intIndiceTemporal2]->setOneConBorde(intInsertBorde);
				objVertices[intIndiceTemporal2]->Add1ConBorde();

				objBordes.push_back(borde1);
				intInsertBorde++;

				intTemporal++;
			}

			if(intNroBordes2-1 == intNroBordes)
			{
				borde2.setVertice1(objVertices[intIndiceTemporal2]);
				borde2.setIndice1(intIndiceTemporal2);
				borde2.setVertice2(objVertices[intIndiceTemporal3]);
				borde2.setIndice2(intIndiceTemporal3);

				objVertices[intIndiceTemporal2]->setOneConVertice(intIndiceTemporal3);
				objVertices[intIndiceTemporal2]->Add1ConVertice();
				objVertices[intIndiceTemporal2]->setOneConBorde(intInsertBorde);
				objVertices[intIndiceTemporal2]->Add1ConBorde();
				
				objVertices[intIndiceTemporal3]->setOneConVertice(intIndiceTemporal2);
				objVertices[intIndiceTemporal3]->Add1ConVertice();
				objVertices[intIndiceTemporal3]->setOneConBorde(intInsertBorde);
				objVertices[intIndiceTemporal3]->Add1ConBorde();

				objBordes.push_back(borde2);
				intInsertBorde++;

				intTemporal++;
			}

			if(intNroBordes3-1 == intNroBordes)
			{
				borde3.setVertice1(objVertices[intIndiceTemporal3]);
				borde3.setIndice1(intIndiceTemporal3);
				borde3.setVertice2(objVertices[intIndiceTemporal1]);
				borde3.setIndice2(intIndiceTemporal1);

				objVertices[intIndiceTemporal1]->setOneConVertice(intIndiceTemporal3);
				objVertices[intIndiceTemporal1]->Add1ConVertice();
				objVertices[intIndiceTemporal1]->setOneConBorde(intInsertBorde);
				objVertices[intIndiceTemporal1]->Add1ConBorde();
				
				objVertices[intIndiceTemporal3]->setOneConVertice(intIndiceTemporal1);
				objVertices[intIndiceTemporal3]->Add1ConVertice();
				objVertices[intIndiceTemporal3]->setOneConBorde(intInsertBorde);
				objVertices[intIndiceTemporal3]->Add1ConBorde();

				objBordes.push_back(borde3);
				intInsertBorde++;

				intTemporal++;
			}

			intNroBordes += intTemporal;
		}
	}

	//Calcula las normales de los vertices
	for(unsigned int i=0;i<=intNroVertices-1;i++)
	{
		if(objVertices[i]->getNroConexionesCara()!=0)
		{
			objVertices[i]->CalcularNormal();

			//cout << i << endl;
		}
	}

	cout << "Numero bordes: " << intNroBordes << endl;
}


void Superificie_Triangular::CargarSuperficieTriangular_1_0()
{
	int x1, y1, z1, t1, x2, y2, z2, t2, x3, y3, z3, t3;
	float fx1, fy1, fz1, fx2, fy2, fz2, fx3, fy3, fz3, fx4, fy4, fz4,
		fx5, fy5, fz5;
	FILE *fileInPuntos;
	FILE *fileInIndices;
	char lineaActual[255];

	fileInIndices = fopen(charFnameIndsSupTriang, "rt");
	fileInPuntos = fopen(charFnamePtosSupTriang, "rt");

	//Almacena los indices

	readstr(fileInIndices,lineaActual);
	sscanf(lineaActual, "Indices: %d\n", &intNroTriangs);

	for (unsigned int loop = 0; loop < intNroTriangs; loop+=3)
	{
		readstr(fileInIndices,lineaActual);
		sscanf(lineaActual, "%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i,"
			, &x1, &y1, &z1, &t1, &x2, &y2, &z2, &t2, &x3, &y3, &z3, &t3);


		Indice objIndiceTemp1(x1, y1, z1);

		objIndices.push_back(objIndiceTemp1);

		Indice objIndiceTemp2(x2, y2, z2);

		objIndices.push_back(objIndiceTemp2);

		Indice objIndiceTemp3(x3, y3, z3);

		objIndices.push_back(objIndiceTemp3);
	}
	fclose(fileInIndices);

	//Almacena los puntos

	readstr(fileInPuntos,lineaActual);
	sscanf(lineaActual, "Vertices: %d\n", &intNroVertices);

	for (unsigned int loop = 0; loop < intNroVertices; loop+=5)
	{
		readstr(fileInPuntos,lineaActual);
		sscanf(lineaActual, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f", 
			&fx1, &fy1, &fz1, &fx2, &fy2, &fz2, &fx3, &fy3, &fz3, &fx4, &fy4, &fz4,
			&fx5, &fy5, &fz5);
		
		Vertice *objVerticeTemp1 = new Vertice(fz1-2.8f, -fx1+22.9, -fy1+43.64f);
		Vertice *objVerticeTemp2 = new Vertice(fz2-2.8f, -fx2+22.9, -fy2+43.64f);
		Vertice *objVerticeTemp3 = new Vertice(fz3-2.8f, -fx3+22.9, -fy3+43.64f);
		Vertice *objVerticeTemp4 = new Vertice(fz4-2.8f, -fx4+22.9, -fy4+43.64f);
		Vertice *objVerticeTemp5 = new Vertice(fz5-2.8f, -fx5+22.9, -fy5+43.64f);
		
		objVertices.push_back(objVerticeTemp1);
		objVertices.push_back(objVerticeTemp2);
		objVertices.push_back(objVerticeTemp3);
		objVertices.push_back(objVerticeTemp4);
		objVertices.push_back(objVerticeTemp5);

	}
	fclose(fileInPuntos);

	//Almacena los triangulos


	for(unsigned int loop = 0; loop < intNroTriangs; loop++)
	{
		Triangulo objTrianguloTemp(objVertices[objIndices[loop].getIndice1()],
			objVertices[objIndices[loop].getIndice2()], 
			objVertices[objIndices[loop].getIndice3()]);

		//Asignando ID al triangulo
		objTrianguloTemp.setID(loop);

		//Calcula Normales de cada triangulo
		objTrianguloTemp.CalcularNormal();

		objTriangulos.push_back(objTrianguloTemp);
	}

}


void Superificie_Triangular::readstr(FILE *f, char *string)
{
	do
	{
		fgets(string, 255, f);
	} while ((string[0] == '/') || (string[0] == '\n'));

}

void Superificie_Triangular::DeterminarConectividad()
{
	unsigned int p1i, p2i, p1j, p2j;
	unsigned int P1i, P2i, P1j, P2j;
	unsigned int i,j,ki,kj;

	for(i=0;i<intNroTriangs-1;i++)
	{
		for(j=i+1;j<intNroTriangs;j++)
		{
			for(ki=0;ki<3;ki++)
			{
				if(!objTriangulos[i].getOneVecino(ki))
				{
					for(kj=0;kj<3;kj++){
						p1i=ki;
						p1j=kj;
						p2i=(ki+1)%3;
						p2j=(kj+1)%3;

						p1i = objTriangulos[i].getOneIndice(p1i);
						p2i = objTriangulos[i].getOneIndice(p2i);
						p1j = objTriangulos[j].getOneIndice(p1j);
						p2j = objTriangulos[j].getOneIndice(p2j);
						
						P1i=((p1i+p2i)-abs((long double)(p1i-p2i)))/2;
						P2i=((p1i+p2i)+abs((long double)(p1i-p2i)))/2;
						P1j=((p1j+p2j)-abs((long double)(p1j-p2j)))/2;
						P2j=((p1j+p2j)+abs((long double)(p1j-p2j)))/2;

						if((P1i==P1j) && (P2i==P2j)){  //they are neighbours
							objTriangulos[i].setOneVecino(j+1,ki);
							objTriangulos[i].setOneVecino(i+1,kj);  
						}
					}
				}
			}
		}
	}
}


